package servlets;

import bd.ConexaoBD;
import beans.BeanUsuario;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Este Servlet trata do login de um usuário no ambiente
 * virtual da UAB-UFSCar
 */
public class ServletLogin extends HttpServlet
{
    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
      response.setContentType("text/html;charset=iso-8859-1");
      PrintWriter out = response.getWriter();
      try
      {
        
        HttpSession sessao = request.getSession(true); //Obtêm a sessão do cliente
        sessao.setMaxInactiveInterval(120); //Define que a sessão expira após 2 minutos
        
        BeanUsuario usr = (BeanUsuario) sessao.getAttribute("loginAgenda"); //Tenta obter o login do usuário
        
        String ultimoAcesso = null; //Armazena o último acesso do cliente
        Cookie listaCookies [] = request.getCookies(); //Obtém a lista de cookies armazenados no cliente
        Cookie cookieUltimoAcesso = null; //Indica qual foi o último acesso do usuário
        if(listaCookies != null && usr!=null) //Então existem cookies armazenados
        {
          for(int i=0; i < listaCookies.length; i++)
          {
            if(listaCookies[i].getName().equals("ultimoAcesso_" + usr.getId())) 
                //se existir cookie específico do usuário, armazena no objeto cookieUltimoAcesso
            {
              cookieUltimoAcesso = listaCookies[i];
              break;
            }
          }
        }
        if(cookieUltimoAcesso != null){ //Então já possui o cookie armazenado no cliente
          ultimoAcesso = cookieUltimoAcesso.getValue(); //Atribui na variável a data do último acesso
        }
        
        String login = request.getParameter("login");
        String password = request.getParameter("password");
        if(usr == null) //Então deve verificar se o usuário forneceu login e senha
        {        
          if(login != null && !login.equals("") && password != null && !password.equals(""))
          {           
            usr= new BeanUsuario(); //cria novo objeto usuário com login e senha
            //digitados para verificar no banco; o método "setSenha" seta a senha criptografada correspondente
            // à digitada.
            usr.setLogin(login);
            usr.setSenha(password);              
            try{
                //conecta ao banco e verifica se dados do login estão corretos (usuário existente e senha correta))
                ConexaoBD connBD = new ConexaoBD();
                Connection conn = connBD.getConexao();
                Statement stmt = (Statement) conn.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT * FROM usuario WHERE (login = '" + usr.getLogin() 
                        + "' AND senha = '" + usr.getSenha() + "')" ); 
                if (rs.next()) { //se existir usuário
                    usr.setNome(rs.getString("nome")); //armazena dados no objeto usr
                    usr.setId(rs.getInt("id"));
                    sessao.setAttribute("loginAgenda", usr); //Adiciona o usuário como um objeto de sessão
                    if(listaCookies != null && usr!=null) //Então existem cookies armazenados
                    {
                      for(int i=0; i < listaCookies.length; i++)
                      {
                        if(listaCookies[i].getName().equals("ultimoAcesso_" + usr.getId()))
                            //se existir cookie específico do usuário, armazena no objeto cookieUltimoAcesso
                        {
                          cookieUltimoAcesso = listaCookies[i];
                          break;
                        }
                      }
                    }
                    if(cookieUltimoAcesso != null){ //Então já possui o cookie armazenado no cliente
                      ultimoAcesso = cookieUltimoAcesso.getValue(); //Atribui na variável a data do último acesso
                    }
                    else{ //se não possui, cria cookie específico do usuário                   
                        SimpleDateFormat dataFormatada = new SimpleDateFormat("dd/MM/yyyy - HH:mm:ss");
                        String data = dataFormatada.format(new Date(System.currentTimeMillis()));
                        ultimoAcesso = data;
                        cookieUltimoAcesso = new Cookie("ultimoAcesso_"+ usr.getId(), data);
                        cookieUltimoAcesso.setMaxAge(2*24*60*60); //Define que o cookie persistirá por 2 dias
                        response.addCookie(cookieUltimoAcesso);   //Envia o outro cookie para o cliente
                     }                
                } else{
                    usr=null;
                }
            }catch (Exception e){ //se der exceção, retorna para login com mensagem de erro.
                System.out.println("Erro banco de dados - " + e);        
                request.setAttribute("erro", "Erro de acesso ao banco. Tente mais tarde.");                    
                RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
                rd.forward(request, response);
            }            
          }
        }
        if(usr != null && cookieUltimoAcesso != null) //Verifica novamente porque agora o login e o último acesso podem estar definidos
        {
            //se tudo está em ordem (login efetuado com sucesso e cookie adequado, redireciona
            //usuário para a página solicitada
              String url = request.getParameter("pagina");
              response.sendRedirect(url);
        }
        else {//se não existe usr ou coockie
            if (sessao.isNew()){ //se sessão nova, retorna msg de sessão expirada via atributo de "request"
                request.setAttribute("erro", "Sess&atilde;o expirada.");
            }else{ //senão
                if (login.equals("") || password.equals(""))// se senha ou login brancos, retorna msg corresponente
                    request.setAttribute("erro", "Voc&ecirc; deve preencher login e senha.");
                else// senão retorna msg de login inválido (ou pq usuário não existe ou pq senha não é correta)
                    request.setAttribute("erro", "Login inv&aacute;lido. Tente novamente.");
            }            
            //redireciona para login
            RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
            rd.forward(request, response);
            //response.sendRedirect("login.jsp");
          }
      }
      finally
      {
        out.close(); //fecha objeto out
      }
    }
    // <editor-fold defaultstate="collapsed" desc="Métodos HttpServlet. Clique no sinal de + à esquerda para editar o código.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
